1 /// Credit BinaryX, SimonDarksideJ
2 ///
Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/page-2#post-1945602
3 ///
Updated by SimonDarksideJ - removed dependency on a custom ScrollRect script. Now implements drag interfaces and standard Scroll Rect.
4 ///
Updated by SimonDarksideJ - major refactoring on updating current position and scroll management
5
6 using
UnityEngine.EventSystems;
7
8 namespace
UnityEngine.UI.Extensions
9 {
10     
[RequireComponent(typeof(ScrollRect))]
11     
[AddComponentMenu("Layout/Extensions/Vertical Scroll Snap")]
12     
public class VerticalScrollSnap : ScrollSnapBase, IEndDragHandler
13     {
14         
void Start()
15         {
16             _isVertical =
true;
17             _childAnchorPoint =
new Vector2(0.5f,0);
18             _currentPage = StartingScreen;
19             UpdateLayout();
20         }
21
22         
void Update()
23         {
24             
if (!_lerp && _scroll_rect.velocity == Vector2.zero)
25             {
26                 
if (!_settled && !_pointerDown)
27                 {
28                     
if (!IsRectSettledOnaPage(_screensContainer.localPosition))
29                     {
30                         ScrollToClosestElement();
31                     }
32                 }
33                 
return;
34             }
35             
else if (_lerp)
36             {
37                 _screensContainer.localPosition = Vector3.Lerp(_screensContainer.localPosition, _lerp_target, transitionSpeed * Time.deltaTime);
38                 
if (Vector3.Distance(_screensContainer.localPosition, _lerp_target) < 0.1f)
39                 {
40                     _lerp =
false;
41                     EndScreenChange();
42                 }
43             }
44
45             CurrentPage = GetPageforPosition(_screensContainer.localPosition);
46
47             
//If the container is moving check if it needs to settle on a page
48             
if (!_pointerDown)
49             {
50                 
if (_scroll_rect.velocity.y > 0.01 || _scroll_rect.velocity.y < -0.01)
51             {
52                     
// if the pointer is released and is moving slower than the threshold, then just land on a page
53                     
if (IsRectMovingSlowerThanThreshold(0))
54                     {
55                         ScrollToClosestElement();
56                     }
57                 }
58             }
59         }
60
61         
private bool IsRectMovingSlowerThanThreshold(float startingSpeed)
62         {
63             
return (_scroll_rect.velocity.y > startingSpeed && _scroll_rect.velocity.y < SwipeVelocityThreshold) ||
64                                 (_scroll_rect.velocity.y < startingSpeed && _scroll_rect.velocity.y > -SwipeVelocityThreshold);
65         }
66
67         
public void DistributePages()
68         {
69             _screens = _screensContainer.childCount;
70             _scroll_rect.verticalNormalizedPosition =
0;
71
72             
float _offset = 0;
73             
float _dimension = 0;
74             Rect panelDimensions = gameObject.GetComponent<RectTransform>().rect;
75             
float currentYPosition = 0;
76             
var pageStepValue = _childSize = (int)panelDimensions.height * ((PageStep == 0) ? 3 : PageStep);
77
78             
for (int i = 0; i < _screensContainer.transform.childCount; i++)
79             {
80                 RectTransform child = _screensContainer.transform.GetChild(i).gameObject.GetComponent<RectTransform>();
81                 currentYPosition = _offset + i * pageStepValue;
82                 child.sizeDelta =
new Vector2(panelDimensions.width, panelDimensions.height);
83                 child.anchoredPosition =
new Vector2(0f, currentYPosition);
84                 child.anchorMin = child.anchorMax = child.pivot = _childAnchorPoint;
85             }
86
87             _dimension = currentYPosition + _offset * -
1;
88
89             _screensContainer.GetComponent<RectTransform>().offsetMax =
new Vector2(0f, _dimension);
90         }

91
92         ///
<summary>
93         ///
Add a new child to this Scroll Snap and recalculate it's children
94         ///
</summary>
95         ///
<param name="GO">GameObject to add to the ScrollSnap</param>
96         
public void AddChild(GameObject GO)
97         {
98             AddChild(GO,
false);
99         }

100
101         ///
<summary>
102         ///
Add a new child to this Scroll Snap and recalculate it's children
103         ///
</summary>
104         ///
<param name="GO">GameObject to add to the ScrollSnap</param>
105         ///
<param name="WorldPositionStays">Should the world position be updated to it's parent transform?</param>
106         
public void AddChild(GameObject GO, bool WorldPositionStays)
107         {
108             _scroll_rect.verticalNormalizedPosition =
0;
109             GO.transform.SetParent(_screensContainer, WorldPositionStays);
110             InitialiseChildObjectsFromScene();
111             DistributePages();
112             
if (MaskArea) UpdateVisible();
113
114             SetScrollContainerPosition();
115         }

116
117         ///
<summary>
118         ///
Remove a new child to this Scroll Snap and recalculate it's children
119         ///
*Note, this is an index address (0-x)
120         ///
</summary>
121         ///
<param name="index"></param>
122         ///
<param name="ChildRemoved"></param>
123         
public void RemoveChild(int index, out GameObject ChildRemoved)
124         {
125             ChildRemoved =
null;
126             
if (index < 0 || index > _screensContainer.childCount)
127             {
128                 
return;
129             }
130             _scroll_rect.verticalNormalizedPosition =
0;
131
132             Transform child = _screensContainer.transform.GetChild(index);
133             child.SetParent(
null);
134             ChildRemoved = child.gameObject;
135             InitialiseChildObjectsFromScene();
136             DistributePages();
137             
if (MaskArea) UpdateVisible();
138
139             
if (_currentPage > _screens - 1)
140             {
141                 CurrentPage = _screens -
1;
142             }
143
144             SetScrollContainerPosition();
145         }

146
147         ///
<summary>
148         ///
Remove all children from this ScrollSnap
149         ///
</summary>
150         ///
<param name="ChildrenRemoved"></param>
151         
public void RemoveAllChildren(out GameObject[] ChildrenRemoved)
152         {
153             
var _screenCount = _screensContainer.childCount;
154             ChildrenRemoved =
new GameObject[_screenCount];
155
156             
for (int i = _screenCount - 1; i >= 0; i--)
157             {
158                 ChildrenRemoved[i] = _screensContainer.GetChild(i).gameObject;
159                 ChildrenRemoved[i].transform.SetParent(
null);
160             }
161
162             _scroll_rect.verticalNormalizedPosition =
0;
163             CurrentPage =
0;
164             InitialiseChildObjectsFromScene();
165             DistributePages();
166             
if (MaskArea) UpdateVisible();
167         }
168
169         
private void SetScrollContainerPosition()
170         {
171             _scrollStartPosition = _screensContainer.localPosition.y;
172             _scroll_rect.verticalNormalizedPosition = (
float)(_currentPage) / (_screens - 1);
173         }

174
175         ///
<summary>
176         ///
used for changing / updating between screen resolutions
177         ///
</summary>
178         
public void UpdateLayout()
179         {
180             _lerp =
false;
181             DistributePages();
182             
if (MaskArea) UpdateVisible();
183             SetScrollContainerPosition();
184             OnCurrentScreenChange(_currentPage);
185         }
186
187         
private void OnRectTransformDimensionsChange()
188         {
189             
if (_childAnchorPoint != Vector2.zero)
190             {
191                 UpdateLayout();
192             }
193         }
194
195         
#region Interfaces
196         ///
<summary>
197         ///
Release screen to swipe
198         ///
</summary>
199         ///
<param name="eventData"></param>
200         
public void OnEndDrag(PointerEventData eventData)
201         {
202             _pointerDown =
false;
203
204             
if (_scroll_rect.vertical)
205             {
206                 
if (UseFastSwipe)
207                 {
208                     
//If using fastswipe - then a swipe does page next / previous
209                     
if ((_scroll_rect.velocity.y > 0 && _scroll_rect.velocity.y > FastSwipeThreshold) ||
210                         _scroll_rect.velocity.y <
0 && _scroll_rect.velocity.y < -FastSwipeThreshold)
211                     {
212                         _scroll_rect.velocity = Vector3.zero;
213                         
if (_startPosition.y - _screensContainer.localPosition.y > 0)
214                         {
215                             NextScreen();
216                         }
217                         
else
218                         {
219                             PreviousScreen();
220                         }
221                     }
222                     
else
223                     {
224                         ScrollToClosestElement();
225                     }
226                 }
227             }
228         }
229         
#endregion
230     }
231 }


Credit BinaryX, SimonDarksideJ

Sourced from - http:forum.unity3d.comthreadsscripts-useful-4-6-scripts-collection.264161page-2#post-1945602

Updated by SimonDarksideJ - removed dependency on a custom ScrollRect script. Now implements drag interfaces and standard Scroll Rect.

Updated by SimonDarksideJ - major refactoring on updating current position and scroll management

If the container is moving check if it needs to settle on a page

if the pointer is released and is moving slower than the threshold, then just land on a page

Add a new child to this Scroll Snap and recalculate it's children

GameObject to add to the ScrollSnap

Add a new child to this Scroll Snap and recalculate it's children

GameObject to add to the ScrollSnap

Should the world position be updated to it's parent transform?

Remove a new child to this Scroll Snap and recalculate it's children

*Note, this is an index address (0-x)

Remove all children from this ScrollSnap

used for changing updating between screen resolutions

Release screen to swipe

If using fastswipe - then a swipe does page next previous




Trò chơi đua xe động vật trong UNITY Engine 114.774 lượt xem

Gõ tìm kiếm nhanh...